package com.googlecode.grt192.HH11.sensor;

import java.util.ArrayList;

import com.googlecode.grt192.HH11.event.HHSwitchEvent;
import com.googlecode.grt192.HH11.event.HHSwitchListener;
import com.googlecode.grtframework.event.SwitchEvent;
import com.googlecode.grtframework.sensor.ISwitch;

/**
 * 
 * A HHToggleSwitch implements IHHSwitch behavior for the first iteration
 * switchboard
 * 
 * The control scheme is as follows:
 * 
 * When in auto mode, a mechanism toggle selects auto and manual states.
 * 
 * When in manual mode, a mechanism toggle selects contraction/retraction state
 * 
 * @author ajc
 * 
 */
public class HHToggleSwitch implements IHHSwitch {

	private static final boolean SELECT_MANUAL = true;
	private static final boolean SELECT_CONTROL = false;

	private ArrayList<HHSwitchListener> switchListeners = new ArrayList<HHSwitchListener>();

	private final ISwitch autoManualSelect;
	private final ISwitch mech;

	// determines if the mechanism switch behaves as a manual mode
	// control(sending contract/retract) or a control mode control (sending
	// auto/manual)
	private boolean controlSelect = SELECT_MANUAL;

	/**
	 * 
	 * @param auto
	 * @param mech
	 */
	public HHToggleSwitch(ISwitch auto, ISwitch mech) {
		this.autoManualSelect = auto;
		this.mech = mech;
	}

	@Override
	public void switchPressed(SwitchEvent arg0) {
		// we don't care about auto button presses

		if (arg0.getSource() == mech) {// mechanism switch flipped up
			if (controlSelect == SELECT_MANUAL) {// retract
				notifyRetract();
			} else if (controlSelect == SELECT_CONTROL) {// enable autonomous
				notifyAuto();
			}
		}
	}

	@Override
	public void switchReleased(SwitchEvent arg0) {
		if (arg0.getSource() == autoManualSelect) { // auto switch selected
			controlSelect = !controlSelect; // toggle control mode
		}

		else if (arg0.getSource() == mech) { // mechanism switch flipped down
			if (controlSelect == SELECT_MANUAL) {// contract
				notifyContract();
			} else if (controlSelect == SELECT_CONTROL) {
				notifyManual();
			}
		}
	}

	private void notifyRetract() {
		HHSwitchEvent ev = new HHSwitchEvent(this);
		for (HHSwitchListener s : switchListeners) {
			s.retract(ev);
		}
	}

	private void notifyContract() {
		HHSwitchEvent ev = new HHSwitchEvent(this);
		for (HHSwitchListener s : switchListeners) {
			s.contract(ev);
		}
	}

	private void notifyAuto() {
		HHSwitchEvent ev = new HHSwitchEvent(this);
		for (HHSwitchListener s : switchListeners) {
			s.auto(ev);
		}
	}

	private void notifyManual() {
		HHSwitchEvent ev = new HHSwitchEvent(this);
		for (HHSwitchListener s : switchListeners) {
			s.manual(ev);
		}
	}

	@Override
	public void addHHToggleSwitchListener(HHSwitchListener swl) {
		switchListeners.add(swl);
	}

	@Override
	public void removeHHToggleSwitchListener(HHSwitchListener swl) {
		switchListeners.remove(swl);
	}

	@Override
	public void startListening() {
		autoManualSelect.addSwitchListener(this);
		mech.addSwitchListener(this);
	}

	@Override
	public void stopListening() {
		autoManualSelect.removeSwitchListener(this);
		mech.removeSwitchListener(this);
	}

}
